﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using Sherwood.Configuration;

namespace Sherwood.Content.SearchServices
{
    internal class SolrSearchProfileHelper<TRecord> where TRecord : IRecord
    {
        private static readonly Dictionary<string, ISearchServiceAuthenticator> Authenticators =
            new Dictionary<string, ISearchServiceAuthenticator>();

        [ThreadStatic]
        private static Dictionary<string, List<ISolrXmlInjector<TRecord>>> InjectorCache;

        internal static ISearchServiceAuthenticator GetAuthenticator(string profileName)
        {
            ISearchServiceAuthenticator authenticator;
            if (!Authenticators.TryGetValue(profileName, out authenticator))
            {
                lock (Authenticators)
                {
                    if (!Authenticators.TryGetValue(profileName, out authenticator))
                    {
                        solrSearchProfile profile = GetProfile(profileName);
                        Type authenticatorType = Type.GetType(profile.authentication.type, true);
                        authenticator = (ISearchServiceAuthenticator)
                                        DependencyInjection.Container.Resolve(authenticatorType, null);
                        Authenticators.Add(profileName, authenticator);
                    }
                }
            }
            return authenticator;
        }

        internal static solrSearchProfile GetProfile(string profileName)
        {
            solrSearchProfile profile;
            var configRepository = DependencyInjection.Resolve<IConfigRepository>();
            string fileName = "SolrSearchProfiles/" + profileName + ".xml";
            using (TextReader reader = configRepository.CreateTextReader(fileName))
                profile = solrSearchProfile.Load(reader);
            return profile;
        }

        internal static List<ISolrXmlInjector<TRecord>> GetInjectors(string profileName)
        {
            if (InjectorCache == null)
                InjectorCache = new Dictionary<string, List<ISolrXmlInjector<TRecord>>>();

            List<ISolrXmlInjector<TRecord>> value;
            if (!InjectorCache.TryGetValue(profileName, out value))
            {
                solrSearchProfile profile = GetProfile(profileName);
                using (XmlReader reader = profile.Untyped.CreateReader())
                {
                    var ns = new XmlNamespaceManager(reader.NameTable);
                    ns.AddNamespace("p", "Sherwood.Content.SearchServices");
                    value = XmlConfiguredPlugins.GetConfiguredInstances<ISolrXmlInjector<TRecord>>(
                        reader, "*/p:injector", ns).ToList();
                    InjectorCache.Add(profileName, value);
                }
            }
            return value;
        }
    }
}
